package fr.lip6.meta.tools;



import java.util.HashMap;
import java.util.Iterator;


import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;

import org.eclipse.gmt.modisco.java.AbstractTypeDeclaration;
import org.eclipse.gmt.modisco.java.BodyDeclaration;
import org.eclipse.gmt.modisco.java.BreakStatement;
import org.eclipse.gmt.modisco.java.ClassDeclaration;
import org.eclipse.gmt.modisco.java.Block;
import org.eclipse.gmt.modisco.java.CatchClause;
import org.eclipse.gmt.modisco.java.ASTNode;
import org.eclipse.gmt.modisco.java.ConstructorDeclaration;
import org.eclipse.gmt.modisco.java.ConstructorInvocation;
import org.eclipse.gmt.modisco.java.ContinueStatement;
import org.eclipse.gmt.modisco.java.DoStatement;
import org.eclipse.gmt.modisco.java.EmptyStatement;
import org.eclipse.gmt.modisco.java.ExpressionStatement;
import org.eclipse.gmt.modisco.java.FieldDeclaration;
import org.eclipse.gmt.modisco.java.ForStatement;
import org.eclipse.gmt.modisco.java.IfStatement;
import org.eclipse.gmt.modisco.java.InterfaceDeclaration;
import org.eclipse.gmt.modisco.java.MethodDeclaration;
import org.eclipse.gmt.modisco.java.MethodInvocation;
import org.eclipse.gmt.modisco.java.Model;
import org.eclipse.gmt.modisco.java.Package;
import org.eclipse.gmt.modisco.java.ReturnStatement;
import org.eclipse.gmt.modisco.java.SingleVariableDeclaration;
import org.eclipse.gmt.modisco.java.Statement;
import org.eclipse.gmt.modisco.java.SuperConstructorInvocation;
import org.eclipse.gmt.modisco.java.SwitchCase;
import org.eclipse.gmt.modisco.java.SwitchStatement;
import org.eclipse.gmt.modisco.java.TryStatement;
import org.eclipse.gmt.modisco.java.TypeAccess;
import org.eclipse.gmt.modisco.java.VariableDeclarationStatement;
import org.eclipse.gmt.modisco.java.WhileStatement;
import org.eclipse.gmt.modisco.java.emf.JavaPackage;
import org.eclipse.gmt.modisco.java.emf.impl.BlockImpl;
import org.eclipse.gmt.modisco.java.emf.impl.BreakStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.CatchClauseImpl;
import org.eclipse.gmt.modisco.java.emf.impl.ConstructorDeclarationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.ConstructorInvocationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.ContinueStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.DoStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.EmptyStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.ExpressionStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.FieldDeclarationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.ForStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.IfStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.MethodDeclarationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.MethodInvocationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.ReturnStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.SuperConstructorInvocationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.SwitchStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.TryStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.VariableDeclarationStatementImpl;
import org.eclipse.gmt.modisco.java.emf.impl.WhileStatementImpl;

import fr.lip6.meta.ple.generation.fh.java.ReadXmiFHJava;
import fr.lip6.meta.ple.generation.strategy.GenerateFromXmiStrategy;

import artefact.generic.Artefact;
import artefact.generic.ConstructionPrimitive;

import artefact.umlClassDiagram.ClassDiagram;
import artefact.umlClassDiagram.CreateAttribute;
import artefact.umlClassDiagram.CreateClass;
import artefact.umlClassDiagram.CreateGeneralization;
import artefact.umlClassDiagram.CreateInterface;
import artefact.umlClassDiagram.CreateOperation;
import artefact.umlClassDiagram.CreateOperationRefinement;
import artefact.umlClassDiagram.CreatePackage;
import artefact.umlClassDiagram.CreateStatement;
import artefact.umlClassDiagram.impl.UmlClassDiagramFactoryImpl;


/**
 *
 * Cette classe charge un "Model" depuis un fichier XMI
 *
 */

public class ModiscoJavaModelLoader {
	HashMap<ASTNode, ASTNode> parentsIfxStatements = new HashMap<ASTNode, ASTNode>();
	Artefact artefact;
	boolean first = false;
	String lien;
	ReadXmiFHJava reader = new ReadXmiFHJava();

	ConstructionPrimitive currentPrimitive = null;

	UmlClassDiagramFactoryImpl factory;
	ClassDiagram product;

	protected static ModiscoJavaModelLoader instance;

	public  ModiscoJavaModelLoader() 
	{
		factory = new UmlClassDiagramFactoryImpl();
		product = factory.createClassDiagram();

	}

	public static ModiscoJavaModelLoader getInstance() 
	{
		if (instance == null) 
			instance = new ModiscoJavaModelLoader();
		return instance;
	}

	public static Model loadModiscoJavaModel(String path) 
	{
		Resource resource = loadJavaModel(path);
		//System.out.println(resource.getContents().size());
		Model model = (Model) resource.getContents().get(0);
		return model;
	}

	public static EObject loadModiscoJavaEoBject(String path) 
	{
		Resource resource = loadJavaModel(path);
		EObject model = resource.getContents().get(0);
		System.out.println("class"+model.eClass().getName());
		return model;
	}

	public static Resource loadJavaModel(String path) 
	{
		Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*",
				new XMIResourceFactoryImpl());
		ResourceSet rs = new ResourceSetImpl();
		URI uri = URI.createFileURI(path);
		System.out.println(uri);
		rs.getPackageRegistry().put(JavaPackage.eNS_URI, JavaPackage.eINSTANCE);
		XMIResourceImpl resource = (XMIResourceImpl) rs.getResource(uri, true);
		return resource;
	}

	public void createArtefact(Model model, String lien) 
	{
		this.lien = lien;
		//for packages
		Iterator<Package> packages = model.getOwnedElements().iterator();
		UmlClassDiagramFactoryImpl factory = new UmlClassDiagramFactoryImpl();
		factory.createClassDiagram();

		while (packages.hasNext()) {
			Package p = packages.next();

			if (!p.isProxy()) 
			{        
				if (lien.contains("bank4")) 
				{
					generatePackage(p);
				} 
				else 
				{
					GenerateFromXmiStrategy.packages.clear();
					GenerateFromXmiStrategy.readsubpackage(p, "");
					for(Package package1 : GenerateFromXmiStrategy.packages) 
					{
						generatePackage(package1);
					}
				}
			}
		}

	}

	private void generatePackage(Package p) 
	{
		if(!p.getName().contains("java"))
		{
			CreatePackage createPackage=factory.createCreatePackage();
			//System.out.println("Createpackage("+p.getName()+","+lien+");");
			createPackage.setName(p.getName());
			createPackage.setLien(lien);
			createPackage.setNode(p);

			if(currentPrimitive==null)
			{
				currentPrimitive=createPackage;
				product.setFirst(createPackage);
			}
			else
			{
				currentPrimitive.setNext(createPackage);
				currentPrimitive=createPackage;
			}

			Iterator<AbstractTypeDeclaration> classs = p.getOwnedElements().iterator();
			while (classs.hasNext())
			{
				AbstractTypeDeclaration ab=classs.next();
				if(ab instanceof ClassDeclaration)
				{
					ClassDeclaration c=(ClassDeclaration) ab;
					generateClass(c, p) ;

				}
				if(ab instanceof InterfaceDeclaration)
				{
					InterfaceDeclaration intf=(InterfaceDeclaration) ab;   
					generateInterface(intf);
				}
			}
		}
	}

	private void generateClass(ClassDeclaration c, ASTNode owenerNode) 
	{
		TypeAccess tp = c.getSuperClass();
		String owner = c.getPackage().getName();
		//System.out.println("CreateClass("+c.getName()+","+owner+","+lien+")");
		CreateClass createClass = factory.createCreateClass();
		createClass.setName(c.getName());
		createClass.setOwener(owner);
		createClass.setLien(lien);
		createClass.setNode(c);
		createClass.setOwnerNode(owenerNode);

		if(tp == null) 
		{
			if (currentPrimitive == null) 
			{
				currentPrimitive = createClass;
				product.setFirst(createClass) ;  
			} 
			else 
			{
				currentPrimitive.setNext(createClass);
				currentPrimitive = createClass;
			}
		} 
		else 
		{
			CreateGeneralization creategeneration = factory.createCreateGeneralization();
			creategeneration.setSuper(tp.getType().getName());
			creategeneration.setSub(c.getName());
			creategeneration.setLien(lien+"::"+c.getPackage().getName());
			creategeneration.setNode(tp);

			if(currentPrimitive == null) 
			{
				currentPrimitive = creategeneration;
				product.setFirst(creategeneration);
			} 
			else 
			{
				currentPrimitive.setNext(creategeneration);
				currentPrimitive=creategeneration;
			}
		}

		EList<BodyDeclaration> bodys = c.getBodyDeclarations();

		for(BodyDeclaration bo : bodys) 
		{
			if(bo instanceof FieldDeclarationImpl) 
			{
				FieldDeclarationImpl fd=(FieldDeclarationImpl) bo;	
				generateAttribute(fd);
			} 
			else 
				if(bo instanceof MethodDeclarationImpl 
						|| bo instanceof ConstructorDeclarationImpl) 
				{
					generateOperation(bo);
				}
		}
	}

	private void generateInterface(InterfaceDeclaration c)
	{
		String owner=c.getPackage().getName();
		//System.out.println("CreateInterface("+c.getName()+","+owner+","+lien+")");
		CreateInterface createClass = factory.createCreateInterface();
		createClass.setName(c.getName());
		createClass.setOwner(owner);
		createClass.setLien(lien);

		if(currentPrimitive==null)
		{
			currentPrimitive=createClass;
			product.setFirst(createClass) ;  
		}
		else 
		{
			currentPrimitive.setNext(createClass);
			currentPrimitive=createClass;
		}

		EList<BodyDeclaration> bodys=c.getBodyDeclarations();
		for(BodyDeclaration bo:bodys)
		{
			if(bo instanceof MethodDeclarationImpl 
					|| bo instanceof ConstructorDeclarationImpl)
			{
				generateOperation(bo);
			}
		}
	}

	private void generateAttribute(FieldDeclaration f) 
	{
		String owner=f.getAbstractTypeDeclaration().getName();
		CreateAttribute createAttribute = factory.createCreateAttribute();
		createAttribute.setName(f.getFragments().get(0).getName());
		createAttribute.setOwner(owner);
		createAttribute.setLien(lien+"::"+f.getAbstractTypeDeclaration().getPackage().getName());
		createAttribute.setNode(f);
		//System.out.println("CreareAttribute("+f.getFragments().get(0).getName()+"," +owner+","+createAttribute.getLien()+")");

		if (currentPrimitive == null) {
			currentPrimitive=createAttribute;
			product.setFirst(createAttribute);
		} else {
			currentPrimitive.setNext(createAttribute);
			currentPrimitive=createAttribute;
		}
	}

	private void generateOperation(BodyDeclaration bodyDecl) {

		String owner="";
		String link="";
		Block  block = null;
		String res = "";
		ConstructionPrimitive createOperation = null;

		if (!(bodyDecl instanceof MethodDeclaration)) 
		{
			ConstructorDeclaration constructor = (ConstructorDeclaration) bodyDecl;

			owner = bodyDecl.getAbstractTypeDeclaration().getName();
			createOperation = factory.createCreateOperation();
			String parameters = "";
			EList<SingleVariableDeclaration> paramsList = null;

			if (bodyDecl instanceof ConstructorDeclaration)
				paramsList = ((ConstructorDeclaration) bodyDecl).getParameters();

			if (paramsList != null) {
				for(SingleVariableDeclaration param : paramsList) {
					parameters += param.getType().getType().getName()+",";
				}
			}
			link=lien
					+	"::"+bodyDecl.getAbstractTypeDeclaration().getPackage().getName()
					+	"::"+parameters	;

			parameters = "(" + parameters.substring(0, parameters.length() < 2 ? 0 : parameters.length()-1) + ")";

			((CreateOperation)createOperation).setName(bodyDecl.getName());
			((CreateOperation)createOperation).setOwener(owner);
			createOperation.setLien(
					lien
					+	"::"+bodyDecl.getAbstractTypeDeclaration().getPackage().getName()
					+	"::"+parameters	);

			createOperation.setNode(constructor);
			//System.err.println("CreateOperation("+bodyDecl.getName()+","+owner+","+createOperation.getLien()+")");

			if (currentPrimitive==null){
				currentPrimitive=createOperation;
				product.setFirst(createOperation) ;  
			} else {
				currentPrimitive.setNext(createOperation);
				currentPrimitive=createOperation;
			}

			block = constructor.getBody();
			res = reader.getConstructorDeclarationAndBodyText(constructor);	
			((CreateOperation)createOperation).setText(res);
		}
		else {
			MethodDeclarationImpl md = (MethodDeclarationImpl) bodyDecl;
			String parameters = "";
			EList<SingleVariableDeclaration> paramsList = null;

			paramsList = md.getParameters();

			if (paramsList != null) 
			{
				for(SingleVariableDeclaration param : paramsList) 
				{
					parameters += param.getType().getType().getName()+",";
				}
			}

			parameters = "(" + parameters.substring(0, parameters.length() < 2 ? 0 : parameters.length()-1) + ")";
			link="";
			if (md.getRedefinedMethodDeclaration() == null) 
			{
				owner = bodyDecl.getAbstractTypeDeclaration().getName();
				/*CreateOperation*/ createOperation = factory.createCreateOperation();

				((CreateOperation)createOperation).setName(bodyDecl.getName());
				((CreateOperation)createOperation).setOwener(owner);
				link=lien+
						"::"+bodyDecl.getAbstractTypeDeclaration().getPackage().getName()
						+	"::"+parameters	;

				createOperation.setLien(link);
				createOperation.setNode(md);		

				//System.out.println("CreateOperation("+bodyDecl.getName()+","+owner+","+createOperation.getLien()+")");

				if (currentPrimitive == null) {
					currentPrimitive = createOperation;
					product.setFirst(createOperation) ;  
				} else {
					currentPrimitive.setNext(createOperation);
					currentPrimitive = createOperation;
				}
				block = md.getBody();
				res = reader.getMethodDeclarationAndBodyText(md);
				((CreateOperation)createOperation).setText(res);
			} 
			else 
			{
				owner = bodyDecl.getAbstractTypeDeclaration().getName();

				/*CreateOperationRefinement*/ createOperation = factory.createCreateOperationRefinement();
				((CreateOperationRefinement)createOperation).setName(bodyDecl.getName());
				((CreateOperationRefinement)createOperation).setOwner(owner);
				((CreateOperationRefinement)createOperation).setNode(bodyDecl);
				((CreateOperationRefinement)createOperation).setSuper((md.getRedefinedMethodDeclaration().getAbstractTypeDeclaration().getName()));
				link = lien
						+	"::"+bodyDecl.getAbstractTypeDeclaration().getPackage().getName()
						+	"::"+parameters	;
				createOperation.setLien(
						lien
						+	"::"+bodyDecl.getAbstractTypeDeclaration().getPackage().getName()
						+	"::"+parameters	);

				//System.out.println("CreateOperationRefinement("+bodyDecl.getName()+","+owner+","+createOperation.getLien()+")");

				if (currentPrimitive == null) {
					currentPrimitive = createOperation;
					product.setFirst(createOperation);
				} else {
					currentPrimitive.setNext(createOperation);
					currentPrimitive = createOperation;
				}

				block = md.getBody();
				res = reader.getMethodDeclarationAndBodyText(md);
				((CreateOperationRefinement)createOperation).setText(res);
			}
		}

		//traitement sur les statements
		//System.out.println("@@@@@@@ Entree dans le corp d'une méthode @@@@@@@\n");
		if(res!="" && block!=null)
			this.handleBlock(block, bodyDecl, link, owner, bodyDecl, createOperation);
	}


	public ClassDiagram getProduct()
	{
		return product;
	}

	public void setProduct(ClassDiagram product)
	{
		this.product = product;
	}


	public void handleBlock(Block b, 
			BodyDeclaration owner, 
			String link, 
			String owner2,
			ASTNode ownerNode,
			ConstructionPrimitive cp) 
	{

		for(Statement st : b.getStatements()) 
		{
			handleStatement(st, owner,link, owner2, ownerNode, cp);
		}
	}

	public void handleStatement(
			Statement st, 
			BodyDeclaration owner,
			String link, 
			String owner2, 
			ASTNode ownerNode,
			ConstructionPrimitive cp) 
	{
		String res;

		if (st instanceof ExpressionStatement) 
		{
			ExpressionStatementImpl es = (ExpressionStatementImpl) st;
			res = reader.readExpressionStatement(es);
			CreateStatement createStatement = factory.createCreateStatement();

			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(es);
			createStatement.setOwnerBlock(cp);

			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				createStatement.setPrevious(currentPrimitive);
				currentPrimitive = createStatement;
			}
		}

		if(st instanceof ReturnStatement) 
		{
			ReturnStatementImpl es = (ReturnStatementImpl) st;
			res = reader.getReturnStatementBody((ReturnStatement) es);
			System.out.println(res);
			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(es);


			createStatement.setOwnerBlock(cp);

			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				createStatement.setPrevious(currentPrimitive);
				currentPrimitive = createStatement;
			}
		}

		if(st instanceof IfStatement) 
		{
			IfStatementImpl ifs = (IfStatementImpl) st;
			handleIfStatement(ifs,owner,link, owner2,ownerNode,cp);
		}

		if(st instanceof ForStatement) {
			ForStatementImpl f = (ForStatementImpl) st;
			handleForStatement(f, owner, link, owner2,ownerNode,cp);
		}

		if(st instanceof WhileStatement)
		{
			WhileStatementImpl w = (WhileStatementImpl) st;
			handleWhileStatement(w, owner, link, owner2,ownerNode,cp);
		}

		if(st instanceof TryStatement) {
			TryStatementImpl tr = (TryStatementImpl) st;
			handleTryStatement(tr, owner, link, owner2,ownerNode,cp);

		}

		if(st instanceof VariableDeclarationStatement)
		{
			VariableDeclarationStatementImpl var = (VariableDeclarationStatementImpl) st;

			res = reader.getVariableDeclarationStatement(var);
			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(var);

			createStatement.setOwnerBlock(cp);
			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				createStatement.setPrevious(currentPrimitive);
				currentPrimitive = createStatement;
			}
		}

		if(st instanceof BreakStatement){
			BreakStatementImpl bsi = (BreakStatementImpl) st;

			res = "break;";
			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(bsi);

			createStatement.setOwnerBlock(cp);
			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				currentPrimitive = createStatement;
			}
		}

		if(st instanceof ContinueStatement){
			ContinueStatementImpl csi = (ContinueStatementImpl) st;
			res = "continue;";
			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(csi);

			createStatement.setOwnerBlock(cp);
			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				currentPrimitive = createStatement;
			}
		}
		if(st instanceof ConstructorInvocation)
		{
			ConstructorInvocationImpl ci = (ConstructorInvocationImpl)st;
			res = reader.getConstructorInvocation(ci);

			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(ci);

			createStatement.setOwnerBlock(cp);
			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				currentPrimitive = createStatement;
			}
		}

		if(st instanceof MethodInvocation)
		{
			MethodInvocationImpl mth = (MethodInvocationImpl)st;
			res=reader.getMethodeInvocation(mth);

			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(mth);

			createStatement.setOwnerBlock(cp);
			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				currentPrimitive = createStatement;
			}	
		}

		if(st instanceof DoStatement)
		{
			DoStatementImpl dw = (DoStatementImpl) st;
			handleDoStatement(dw, owner, link, owner2,ownerNode,cp);
		}

		if(st instanceof SwitchStatement){
			System.out.println("existe switch");
			SwitchStatementImpl ss = (SwitchStatementImpl) st;
			handleSwitchStatement(ss,owner,link,owner2,ownerNode,cp);
		}

		if(st instanceof SuperConstructorInvocation){
			SuperConstructorInvocationImpl sci = (SuperConstructorInvocationImpl)st;
			res = reader.getSuperConstruteurInvocation(sci);
			System.out.println(res);
			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(sci);

			createStatement.setOwnerBlock(cp);
			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				currentPrimitive = createStatement;
			}
		}

		if(st instanceof EmptyStatement){
			EmptyStatementImpl emp = (EmptyStatementImpl)st;
			res = reader.getEmptyStatement(emp);

			CreateStatement createStatement = factory.createCreateStatement();
			createStatement.setOwnerOperation(owner.getName());
			createStatement.setText(res);
			createStatement.setOwnerClass(owner2);
			createStatement.setLien(link);

			createStatement.setOwnerNode(ownerNode);
			createStatement.setNode(emp);

			createStatement.setOwnerBlock(cp);
			if (currentPrimitive == null) {
				currentPrimitive = createStatement;
				product.setFirst(createStatement);
			} else {
				currentPrimitive.setNext(createStatement);
				createStatement.setPrevious(currentPrimitive);
				currentPrimitive = createStatement;
			}
		}

	}

	private void handleSwitchStatement(SwitchStatementImpl ss,
			BodyDeclaration owner, String link, String owner2,
			ASTNode ownerNode, ConstructionPrimitive cp) {

		String res = reader.getStatement(ss);
		CreateStatement createStatement = factory.createCreateStatement();
		createStatement.setOwnerOperation(owner.getName());
		createStatement.setText(res);
		createStatement.setOwnerClass(owner2);

		createStatement.setLien(link);

		createStatement.setNode(ss);
		createStatement.setOwnerNode(ownerNode);

		createStatement.setOwnerBlock(cp);

		if (currentPrimitive == null) {
			currentPrimitive = createStatement;
			product.setFirst(createStatement);
		} else {
			currentPrimitive.setNext(createStatement);
			createStatement.setPrevious(currentPrimitive);
			currentPrimitive = createStatement;
		}

		//regarder les statements du switch
		Statement ownerCase = null;
		for(Statement s : ss.getStatements()){
			if(s instanceof SwitchCase)
				ownerCase = s;
			else {
				this.handleStatement(s, owner, link, owner2, ownerCase, createStatement);
			}
		}
	}

	private void handleTryStatement(
			TryStatement t, 
			BodyDeclaration owner,
			String link, 
			String owner2,
			ASTNode ownerNode,
			ConstructionPrimitive cp) {

		String res = reader.getStatement(t);
		CreateStatement createStatement = factory.createCreateStatement();
		createStatement.setOwnerOperation(owner.getName());
		createStatement.setText(res);
		createStatement.setOwnerClass(owner2);

		createStatement.setLien(link);

		createStatement.setNode(t);
		createStatement.setOwnerNode(ownerNode);

		createStatement.setOwnerBlock(cp);

		if (currentPrimitive == null) {
			currentPrimitive = createStatement;
			product.setFirst(createStatement);
		} else {
			currentPrimitive.setNext(createStatement);
			createStatement.setPrevious(currentPrimitive);
			currentPrimitive = createStatement;
		}

		BlockImpl rst = (BlockImpl) t.getBody();
		this.handleBlock(rst, owner, link, owner2, t,createStatement);
		Iterator<CatchClause> catchecluses = t.getCatchClauses().iterator();

		while(catchecluses.hasNext()) {
			CatchClause c = (CatchClauseImpl) catchecluses.next();
			BlockImpl b= (BlockImpl) c.getBody();
			this.handleBlock(b, owner, link, owner2, c, createStatement);
		}

		BlockImpl fin = (BlockImpl) t.getFinally();
		if(fin != null) {
			this.handleBlock(fin, owner, link, owner2, fin, createStatement);
		}
	}

	private void handleWhileStatement(
			WhileStatement w, 
			BodyDeclaration owner,
			String link, 
			String owner2,
			ASTNode ownerNode,
			ConstructionPrimitive cp) {

		String res = reader.getStatement(w);
		CreateStatement createStatement = factory.createCreateStatement();
		createStatement.setOwnerOperation(owner.getName());
		createStatement.setText(res);
		createStatement.setOwnerClass(owner2);
		createStatement.setLien(link);

		createStatement.setOwnerNode(ownerNode);
		createStatement.setNode(w);

		createStatement.setOwnerBlock(cp);

		if (currentPrimitive == null) {
			currentPrimitive = createStatement;
			product.setFirst(createStatement);
		} else {
			currentPrimitive.setNext(createStatement);
			createStatement.setPrevious(currentPrimitive);
			currentPrimitive = createStatement;
		}

		Statement body = w.getBody();

		if (body instanceof ExpressionStatementImpl) 
		{
			this.handleStatement(w.getBody(), owner, link, owner2,w, createStatement);

		} 
		else if (body instanceof BlockImpl) 
		{
			this.handleBlock((BlockImpl) body, owner, link, owner2, w, createStatement);
		}
	}

	private void handleForStatement(ForStatement f, BodyDeclaration owner,
			String link, String owner2, ASTNode ownerNode, ConstructionPrimitive cp) {

		String res = reader.getStatement(f);
		CreateStatement createStatement = factory.createCreateStatement();
		createStatement.setOwnerOperation(owner.getName());
		createStatement.setText(res);
		createStatement.setOwnerClass(owner2);
		createStatement.setLien(link);

		createStatement.setNode(f);
		createStatement.setOwnerNode(ownerNode);

		createStatement.setOwnerBlock(cp);

		//System.out.println("CreateForStatement ");

		if (currentPrimitive == null) 
		{
			currentPrimitive = createStatement;
			product.setFirst(createStatement);
		} 
		else {
			currentPrimitive.setNext(createStatement);
			createStatement.setPrevious(currentPrimitive);
			currentPrimitive = createStatement;
		}


		BlockImpl rst = (BlockImpl) f.getBody();
		this.handleBlock(rst, owner, link, owner2, f, createStatement);

	}

	private void handleIfStatement(IfStatementImpl ifs, BodyDeclaration owner,
			String link, String owner2, ASTNode ownerNode, ConstructionPrimitive cp) 
	{

		String res = reader.getStatement(ifs);
		CreateStatement createStatement = factory.createCreateStatement();
		createStatement.setOwnerClass(owner2);
		createStatement.setOwnerOperation(owner.getName());
		createStatement.setText(res);
		createStatement.setLien(link);

		createStatement.setNode(ifs );
		createStatement.setOwnerNode(ownerNode);

		createStatement.setOwnerBlock(cp);
		if (currentPrimitive == null) {
			currentPrimitive = createStatement;
			product.setFirst(createStatement);
		} 
		else {
			currentPrimitive.setNext(createStatement);
			createStatement.setPrevious(currentPrimitive);
			currentPrimitive = createStatement;
		}


		if(ifs.getThenStatement() instanceof BlockImpl) 
		{
			BlockImpl st1 = (BlockImpl) ifs.getThenStatement();
			this.handleBlock(st1, owner, link, owner2,ifs, createStatement);
		} 
		else 
		{
			this.handleStatement(ifs.getThenStatement(), owner, link, owner2, ifs, createStatement);
		}

		if(ifs.getElseStatement() instanceof BlockImpl) 
		{
			BlockImpl st = (BlockImpl) ifs.getElseStatement();
			this.handleBlock(st, owner, link, owner2,ifs.getElseStatement(), createStatement);
		} 
		else if(ifs.getElseStatement() == null) {} 
		else 
		{
			this.handleStatement(ifs.getElseStatement(), owner, link, owner2,ifs.getElseStatement(), createStatement);
		}
	}

	private void handleDoStatement(
			DoStatement w, 
			BodyDeclaration owner,
			String link, 
			String owner2,
			ASTNode ownerNode,
			ConstructionPrimitive cp) {

		String res = reader.getStatement(w);
		CreateStatement createStatement = factory.createCreateStatement();
		createStatement.setOwnerOperation(owner.getName());
		createStatement.setText(res);
		createStatement.setOwnerClass(owner2);
		createStatement.setLien(link);

		createStatement.setOwnerNode(ownerNode);
		createStatement.setNode(w);

		createStatement.setOwnerBlock(cp);

		if (currentPrimitive == null) {
			currentPrimitive = createStatement;
			product.setFirst(createStatement);
		} else {
			currentPrimitive.setNext(createStatement);
			createStatement.setPrevious(currentPrimitive);
			currentPrimitive = createStatement;
		}

		Statement body = w.getBody();

		if (body instanceof ExpressionStatementImpl) 
		{
			this.handleStatement(w.getBody(), owner, link, owner2,w, createStatement);

		} 
		else if (body instanceof BlockImpl) 
		{
			this.handleBlock((BlockImpl) body, owner, link, owner2, w, createStatement);
		}
	}
}